package com.iot08.api.service;

import com.iot08.api.utils.ResponseMapUtil;
import com.iot08.api.vo.request.UserSmsNotifyBuyReqBodyFormVo;
import com.iot08.api.vo.request.base.BodyFormAccount;
import com.iot08.common.entity.app.SmsNotifyServer;
import com.iot08.common.entity.app.UserGoldCoin;
import com.iot08.common.entity.app.UserSmsNotify;
import com.iot08.common.service.base.BaseService;
import com.iot08.common.utils.response.ResponseMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;


/**
 * @author cwj
 * @description
 * @date 2025/3/16 16:06
 **/
@Slf4j
@Service
public class UserSmsNotifyService extends BaseService<UserSmsNotify> {

    @Resource
    private SmsNotifyServerService smsNotifyServerService;

    @Resource
    private UserGoldCoinService userGoldCoinService;

    @Resource
    private GoldCoinBuyerOrderService goldCoinBuyerOrderService;

    /**
     * @description 查询用户拥有的短信服务信息
     * @author cwj
     * @param [bodyForm]
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2025/3/16 16:14
     **/
    public ResponseMap queryUserSmsNotify(BodyFormAccount bodyForm) {
        UserSmsNotify userSmsNotify = queryEffeftUserSmsNotifyByOpenId(bodyForm.getOpenid());
        ResponseMap res  = ResponseMap.success();
        res.put("userSmsNotify",userSmsNotify);
        return res;
    }

    /**
     * @description 根据用户id查询用户有效的短信通知信息
     * @author cwj
     * @param [openId]
     * @return com.iot08.common.entity.app.UserSmsNotify
     * @date @time 2025/3/16 17:01
     **/
    public UserSmsNotify queryEffeftUserSmsNotifyByOpenId(String openId) {
        Query query = new Query(Criteria.where("openid").is(openId).and("isEffect").is(1)).limit(1);
        UserSmsNotify userSmsNotify = this.findOne(query);
        return userSmsNotify;
    }

    /**
     * @description 用户用金币购买短信服务
     * @author cwj
     * @param [vo]
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2025/3/16 16:53
     **/
    @Transactional
    public ResponseMap buyUserSmsNotify(UserSmsNotifyBuyReqBodyFormVo vo){
        ResponseMap res = ResponseMap.fail();
        Integer isGoldCoinInsufficient = 0;
        if(ObjectUtils.isEmpty(vo.getSnId()) || ObjectUtils.isEmpty(vo.getSmsNotifyTime())) {
            ResponseMapUtil.settingFailRes(res, isGoldCoinInsufficient,"参数缺失，未传购买服务的id或购买服务的次数");
            return res;
        }
        //查询短信服务套餐
        SmsNotifyServer smsNotifyServer = smsNotifyServerService.findById(new ObjectId(vo.getSnId()));
        if(ObjectUtils.isEmpty(smsNotifyServer)) {
            ResponseMapUtil.settingFailRes(res, isGoldCoinInsufficient,"用户所选套餐不存在，请重新选择存在的套餐");
            return res;
        }
        //计算花费的金币总数
        Integer costGoldCoinTotal = smsNotifyServer.getPrice() * vo.getSmsNotifyTime();
        //用户购买短信服务的总条数
        Integer smsTotal = smsNotifyServer.getSmsNum() * vo.getSmsNotifyTime();
        //检查用户金币数是否足够
        UserGoldCoin userGoldCoin = userGoldCoinService.queryEffectUserGoldCoinByOpenId(vo.getOpenid());
        if(ObjectUtils.isEmpty(userGoldCoin) || ObjectUtils.isEmpty(userGoldCoin.getGoldCoinTotal()) || costGoldCoinTotal > userGoldCoin.getGoldCoinTotal()) {
            isGoldCoinInsufficient = 1;
            ResponseMapUtil.settingFailRes(res, isGoldCoinInsufficient,"用户没有购买金币或金币数量不足以支付此次短信通知服务的购买订单");
            return res;
        }
        //创建金币购买订单即订单详细记录
        String orderId = goldCoinBuyerOrderService.createSmsNotifyGoldCoinBuyerOrder(smsNotifyServer,vo.getSmsNotifyTime(),costGoldCoinTotal,vo.getOpenid(),1,userGoldCoin.getGoldCoinTotal());
        boolean isSaveSuccess = false;
        if(StringUtils.isNotEmpty(orderId)) {
            //查询用户购买短信服务的记录
            UserSmsNotify userSmsNotify = queryUserSmsNotifyByOpenId(vo.getOpenid());
            if(ObjectUtils.isEmpty(userSmsNotify)) {
                userSmsNotify =  buildingUserSmsNotify(vo, orderId, costGoldCoinTotal,costGoldCoinTotal, smsTotal,smsTotal,smsTotal);
                userSmsNotify = this.save(userSmsNotify);
                if(!StringUtils.isEmpty(userSmsNotify.getId())) {
                    isSaveSuccess = true;
                }
            } else {
                //更新用户拥有的短信服务信息
                if(Integer.valueOf(1).equals(userSmsNotify.getIsEffect())) {
                    isSaveSuccess = updateUserSmsNotify(userSmsNotify.getId(), vo.getSnId(),orderId,userSmsNotify.getGoldCoinTotal()+costGoldCoinTotal,
                            costGoldCoinTotal, userSmsNotify.getSmsTotal() + smsTotal,userSmsNotify.getSmsSurplusTotal()+smsTotal, smsTotal,1);
                    
                } else {
                    isSaveSuccess = updateUserSmsNotify(userSmsNotify.getId(), vo.getSnId(),orderId,costGoldCoinTotal,
                            costGoldCoinTotal, smsTotal,smsTotal, smsTotal,1);

                }
            }
        }
        if(isSaveSuccess) {
            //减去用户消费的金币
            userGoldCoinService.updateUserGoldCoinNumById(userGoldCoin.getId(),costGoldCoinTotal);
        }
        ResponseMapUtil.settingFailRes(res, isGoldCoinInsufficient,"用户短信通知服务购买失败，用户保存购买的短信信息失败");
        return isSaveSuccess ? ResponseMap.success():res;
    }

    /**
     * @description 构建用户短信服务通知对象
     * @author cwj
     * @param [vo, orderId, costGoldCoinTotal, currentGoldCoinNum, smsTotal, smsSurplusTotal, currentSmsNum]
     * @return com.iot08.common.entity.app.UserSmsNotify
     * @date @time 2025/3/16 18:09
     **/
    private UserSmsNotify buildingUserSmsNotify(UserSmsNotifyBuyReqBodyFormVo vo, String orderId, Integer costGoldCoinTotal, Integer currentGoldCoinNum,
                                                Integer smsTotal, Integer smsSurplusTotal, Integer currentSmsNum) {
        UserSmsNotify userSmsNotify =  new UserSmsNotify();
        userSmsNotify.setOpenid(vo.getOpenid());
        userSmsNotify.setSid(vo.getSnId());
        userSmsNotify.setOrderid(orderId);
        userSmsNotify.setGoldCoinTotal(costGoldCoinTotal);
        userSmsNotify.setCurrentGoldCoinNum(currentGoldCoinNum);
        userSmsNotify.setSmsTotal(smsTotal);
        userSmsNotify.setSmsSurplusTotal(smsSurplusTotal);
        userSmsNotify.setCurrentSmsNum(currentSmsNum);
        userSmsNotify.setIsEffect(1);
        userSmsNotify.setIsOpenLowPowerSmsNotify(0);
        userSmsNotify.setIsOpenFenceSmsNotify(0);
        userSmsNotify.setCreateTime(new Date());
        userSmsNotify.setUpdateTime(new Date());
        return userSmsNotify;
    }
    
    /**
     * @description 更新用户购买的短信服务信息
     * @author cwj
     * @param [id, snId, orderId, goldCoinTotal, currentGoldCoinNum, smsTotal, smsSurplusTotal, currentSmsNum, isEffect]
     * @return boolean
     * @date @time 2025/3/16 18:26
     **/
    private boolean updateUserSmsNotify(String id, String snId, String orderId, Integer goldCoinTotal, Integer currentGoldCoinNum,
                                        Integer smsTotal, Integer smsSurplusTotal, Integer  currentSmsNum, Integer isEffect) {
        Update update = new Update();
        update.set("sid",snId);
        update.set("orderid",orderId);
        update.set("goldCoinTotal",goldCoinTotal);
        update.set("currentGoldCoinNum",currentGoldCoinNum);
        update.set("smsTotal",smsTotal);
        update.set("smsSurplusTotal",smsSurplusTotal);
        update.set("currentSmsNum",currentSmsNum);
        update.set("isEffect",isEffect);
        this.updateById(new ObjectId(id),update);
        return true;
    }

    /**
     * @description 查询用户购买短信服务的记录
     * @author cwj
     * @param [openId]
     * @return com.iot08.common.entity.app.UserSmsNotify
     * @date @time 2025/3/16 17:11
     **/
    public UserSmsNotify queryUserSmsNotifyByOpenId(String openId) {
        Query query = new Query(Criteria.where("openid").is(openId)).limit(1);
        return this.findOne(query);
    }

    /**
     * @description 更新smsSurplusTotal
     * @author cwj
     * @param [id, num]
     * @return void
     * @date @time 2025/3/30 15:47
     **/
    public void updateUserSmsSurplusTotal(String id,int num) {
        Update update = new Update().inc("smsSurplusTotal", num);
        this.updateById(new ObjectId(id),update);
    }

}
